package okw.database;

import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;

import okw.gui.MainWindowO;
import okw.network.ConnectionO;
import okw.network.StanO;
import core.messages.VoteMsg;
import core.modules.LoggerModule;
import core.modules.database.corebase.SummaryPackageCore;
import core.modules.database.corebase.VoteCore;
import core.modules.database.corebase.VotesPackageCore;

public class Packer extends Thread {
	
	private long sleepTime = 10000;
	private VotesPackageCore votesPackageCore = null;
	private DatabaseManager db = null;
	private ConnectionO cm = null;
	private VoteMsg voteMsg = null;
	private StanO stanO = null;
	private ArrayList<VotesPackageCore> votesPackageCoreQueue = null;
	private SummaryPackageCore summaryPackageCore = null;
	private static LoggerModule logger = null;
	
	public Packer() {
		this.cm = new ConnectionO();
		initializeLogger();
		initializeQueue();
	}
	
	public Packer(ConnectionO cm, StanO stanO) {
		this.cm = cm;
		this.stanO = stanO;
		initializeLogger();
		initializeQueue();
	}
	
	public Packer(long sleepTime){
		this.sleepTime = sleepTime;
		this.cm = new ConnectionO();
		initializeLogger();
		initializeQueue();
	}
	
	private void initializeQueue() {
		db = DatabaseManager.getInstance();
		summaryPackageCore = db.getSummaryPackage();
		ArrayList<VotesPackageCore> queue = db.getUnsendVotesPackages();
		if (queue != null){
			votesPackageCoreQueue = new ArrayList<VotesPackageCore>(queue);
		} else
			votesPackageCoreQueue = new ArrayList<VotesPackageCore>();
		
	}
	
	private void initializeLogger(){
		try {
	    	logger = new LoggerModule("packer.log", null);
	    } catch (IOException e) {
	    	e.printStackTrace();
			throw new RuntimeException("Problems with creating the log files");
	    }
		logger.getLoggerInstance().log(Level.FINE, "Start Packera");
	}
	
	public void run(){
		boolean timeout = false;
		
		while (!timeout) {
			try {
				sleep(sleepTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			if (!votesPackageCoreQueue.isEmpty()) {
				ArrayList<VotesPackageCore> tmpPackageQueue = new ArrayList<VotesPackageCore>(votesPackageCoreQueue);
				for (VotesPackageCore packageCore : tmpPackageQueue) {
					votesPackageCoreQueue.remove(packageCore);
					voteMsg = new VoteMsg(stanO.getNr(), "Paczka z głosami", db.get(Election.class, MainWindowO.electionNr).getName());
					voteMsg.setVotesPackageCore(packageCore);
					try {
						cm.sendUp(voteMsg);
						logger.getLoggerInstance().log(Level.FINE, "Wysłanie paczki z głosami dla Election: "+voteMsg.getElectionName());
					} catch (Exception e) {
						e.printStackTrace();
						votesPackageCoreQueue.add(packageCore);
					}
				}
			}
			db = DatabaseManager.getInstance();
			synchronized(db) {
				votesPackageCore = db.getVotes();
				if (votesPackageCore != null){
					voteMsg = new VoteMsg(stanO.getNr(), "Paczka z głosami", db.get(Election.class, MainWindowO.electionNr).getName());
					voteMsg.setVotesPackageCore(votesPackageCore);
					try {
						cm.sendUp(voteMsg);
						logger.getLoggerInstance().log(Level.FINE, "Wysłanie paczki z głosami dla Election: "+voteMsg.getElectionName());
					} catch (Exception e) {
						e.printStackTrace();
						votesPackageCoreQueue.add(votesPackageCore);
					}	
				}
				SummaryPackageCore tmpSummaryPackageCore;
				if (summaryPackageCore != null){
					tmpSummaryPackageCore = summaryPackageCore;
					summaryPackageCore = null;
				} else
					tmpSummaryPackageCore = db.getSummaryPackage();
				if (tmpSummaryPackageCore != null) {
					voteMsg = new VoteMsg(stanO.getNr(), "Paczka podsumowująca", db.get(Election.class, MainWindowO.electionNr).getName());
					voteMsg.setSummaryPackageCore(tmpSummaryPackageCore);
					try {
						cm.sendUp(voteMsg);
						logger.getLoggerInstance().log(Level.FINE, "Wysłanie paczki podsumowującej dla Election: "+voteMsg.getElectionName());
					} catch (Exception e) {
						e.printStackTrace();
						summaryPackageCore = tmpSummaryPackageCore;
					}
				}
			}
		}
	}
}
